<?php

declare(strict_types=1);

namespace DreamCat\StateMachine\Impl;

use DreamCat\StateMachine\Error\DefineConfigException;
use DreamCat\StateMachine\Factory\MachineFactory;
use DreamCat\StateMachine\Parser\ConfigParserInterface;
use DreamCat\StateMachine\Popo\MachineDefine;
use DreamCat\StateMachine\StateMachineProviderInterface;
use DreamCat\StateMachine\StateMachineTransferInterface;
use Psr\Container\ContainerInterface;

/**
 * 状态机汇总提供器
 * @author vijay
 */
class StateMachineProvider implements StateMachineProviderInterface
{
    /** @var MachineFactory 状态机构建工厂 */
    private MachineFactory $machineFactory;
    /** @var MachineDefine 状态机解析的定义 */
    private MachineDefine $machineDefine;
    /** @var StateMachineTransferInterface 状态机转移对象 */
    private StateMachineTransferInterface $stateMachineTransfer;

    /**
     * StateMachineProvider constructor.
     * @param ContainerInterface $container 关联的IoC容器
     * @param ConfigParserInterface $configParser 配置解析器
     * @throws DefineConfigException
     */
    public function __construct(
        private ContainerInterface $container,
        ConfigParserInterface $configParser
    ) {
        $this->machineDefine = $configParser->parseConfig();
    }

    /** @inheritDoc */
    public function define(): MachineDefine
    {
        return $this->machineDefine;
    }

    /** @inheritDoc */
    public function factory(): MachineFactory
    {
        if (!isset($this->machineFactory)) {
            $this->machineFactory = $this->container->get($this->machineDefine->getMachineFactoryClass());
        }
        return $this->machineFactory;
    }

    /** @inheritDoc */
    public function container(): ContainerInterface
    {
        return $this->container;
    }

    /** @inheritDoc */
    public function transfer(): StateMachineTransferInterface
    {
        if (!isset($this->stateMachineTransfer)) {
            $this->stateMachineTransfer = new StateMachineTransfer($this);
        }
        return $this->stateMachineTransfer;
    }
}

# end of file
